﻿namespace HiMap.Carto
{
    using HiMap.Geometry;
    using System;
    using System.Collections.Generic;
    using System.Text;

    internal class FeatureClass : IFeature
    {
        private ClassClass _Class;
        private bool _isDataUpdate;
        private bool _isGeometryUpdate;
        private IGeometry _Shape;
        protected internal int DataIndex;
        private List<object> listValue;

        internal FeatureClass(IFeatureClass Class)
        {
            this.Ini(Class);
            this.DataIndex = -1;
            for (int i = 0; i < Class.Fields.FieldCount; i++)
            {
                this.listValue.Add("");
            }
        }

        internal FeatureClass(IFeatureClass Class, int DataIndex)
        {
            this.Ini(Class);
            this.DataIndex = DataIndex;
            int num = HiMap.Carto.VC.KWG_FEATURELAYER_GET_GEOMETRY(Class.InPtr, DataIndex);
            int num2 = HiMap.Carto.VC.KWG_FEATURELAYER_GET_DATAROW(Class.InPtr, DataIndex);
            for (int i = 0; i < Class.Fields.FieldCount; i++)
            {
                StringBuilder builder = new StringBuilder(0xff);
                HiMap.Carto.VC.KWG_DATAROW_GET_CELL(num2, i, builder);
                this.listValue.Add(builder.ToString());
            }
            this.setGeometry(num);
            HiMap.Carto.VC.KWG_GEOMETRY_DELETE(num);
            HiMap.Carto.VC.KWG_DATAROW_DELETE(num2);
            this._isGeometryUpdate = false;
            this._isDataUpdate = false;
        }

        object IFeature.GetValue(int Index)
        {
            return this.listValue.get_Item(Index);
        }

        void IFeature.Save()
        {
            IFeatureClass class2 = this._Class as IFeatureClass;
            if (!class2.IsEdit())
            {
                return;
            }
            IFeatureClass class3 = (IFeatureClass) this._Class;
            if (this._Shape.Type != class3.GeometryType)
            {
                return;
            }
            int num = 0;
            if (this._isGeometryUpdate)
            {
                int num2 = HiMap.Carto.VC.KWG_FEATURELAYER_GET_GEOMETRYTYPE(class3.InPtr);
                if (this._Shape == null)
                {
                    int[] numArray = new int[1];
                    num = HiMap.Carto.VC.KWG_GEOMETRY_CREATE(0, 0, ref numArray[0]);
                }
                else
                {
                    int[] numArray2 = null;
                    IGeometryCollection geometrys = null;
                    IPointCollection geometry = null;
                    switch (num2)
                    {
                        case 0x15:
                        case 1:
                        case 11:
                        {
                            numArray2 = new int[] { 1 };
                            num = HiMap.Carto.VC.KWG_GEOMETRY_CREATE(num2, 1, ref numArray2[0]);
                            HiMap.Carto.VC.KWG_GEOMETRY_SET_POINTX(num, 0, ((IPoint) this._Shape).X);
                            HiMap.Carto.VC.KWG_GEOMETRY_SET_POINTY(num, 0, ((IPoint) this._Shape).Y);
                            HiMap.Carto.VC.KWG_GEOMETRY_MATH_BOUND(num);
                            double x = 0;
                            double y = 0;
                            HiMap.Carto.VC.KWG_GEOMETRY_GET_POINTX(num, 0, ref x);
                            HiMap.Carto.VC.KWG_GEOMETRY_GET_POINTY(num, 0, ref y);
                            goto Label_0259;
                        }
                        case 0x16:
                        case 0x18:
                        case 2:
                        case 4:
                        case 12:
                        case 14:
                            goto Label_0259;

                        case 0x17:
                        case 0x19:
                        case 0x1c:
                        case 0x12:
                        case 3:
                        case 5:
                        case 8:
                        case 13:
                        case 15:
                            geometrys = (IGeometryCollection) this._Shape;
                            numArray2 = new int[geometrys.GeometryCount];
                            for (int i = 0; i < geometrys.GeometryCount; i++)
                            {
                                geometry = (IPointCollection) geometrys.GetGeometry(i);
                                numArray2[i] = geometry.PointCount;
                            }
                            num = HiMap.Carto.VC.KWG_GEOMETRY_CREATE(num2, geometrys.GeometryCount, ref numArray2[0]);
                            for (int j = 0; j < geometrys.GeometryCount; j++)
                            {
                                geometry = (IPointCollection) geometrys.GetGeometry(j);
                                for (int k = 0; k < geometry.PointCount; k++)
                                {
                                    HiMap.Carto.VC.KWG_GEOMETRY_SET_SEGMENT_POINTX(num, j, k, geometry.GetPoint(k).X);
                                    HiMap.Carto.VC.KWG_GEOMETRY_SET_SEGMENT_POINTY(num, j, k, geometry.GetPoint(k).Y);
                                }
                            }
                            HiMap.Carto.VC.KWG_GEOMETRY_MATH_BOUND(num);
                            goto Label_0259;
                    }
                }
            }
        Label_0259:
            if (this.DataIndex == -1)
            {
                int num8 = 0;
                if (class3.FeatureClassType == FeatureClassType.ShapeLayer)
                {
                    num8 = HiMap.Carto.VC.KWG_SHAPELAYER_CREATEROW(class3.InPtr);
                }
                else
                {
                    num8 = HiMap.Carto.VC.KWG_MEMLAYER_CREATEROW(class3.InPtr);
                }
                for (int m = 0; m < this.listValue.get_Count(); m++)
                {
                    HiMap.Carto.VC.KWG_DATAROW_SET_CELL(num8, m, new StringBuilder(this.listValue.get_Item(m).ToString()));
                }
                int num10 = HiMap.Carto.VC.KWG_FEATURELAYER_ADD_FEATURE(class3.InPtr, num8, num);
                this.DataIndex = num10;
                HiMap.Carto.VC.KWG_DATAROW_CLEAR(num8);
                HiMap.Carto.VC.KWG_DATAROW_DELETE(num8);
                HiMap.Carto.VC.KWG_GEOMETRY_CLEAR(num);
                HiMap.Carto.VC.KWG_GEOMETRY_DELETE(num);
            }
            else
            {
                if (this._isDataUpdate)
                {
                    int num11 = 0;
                    if (class3.FeatureClassType == FeatureClassType.ShapeLayer)
                    {
                        num11 = HiMap.Carto.VC.KWG_SHAPELAYER_CREATEROW(class3.InPtr);
                    }
                    else
                    {
                        num11 = HiMap.Carto.VC.KWG_MEMLAYER_CREATEROW(class3.InPtr);
                    }
                    for (int n = 0; n < this.listValue.get_Count(); n++)
                    {
                        HiMap.Carto.VC.KWG_DATAROW_SET_CELL(num11, n, new StringBuilder(this.listValue.get_Item(n).ToString()));
                    }
                    HiMap.Carto.VC.KWG_FEATURELAYER_UPDATE_DATAROW(class3.InPtr, this.DataIndex, num11);
                    HiMap.Carto.VC.KWG_DATAROW_CLEAR(num11);
                    HiMap.Carto.VC.KWG_DATAROW_DELETE(num11);
                }
                if (this._isGeometryUpdate)
                {
                    HiMap.Carto.VC.KWG_FEATURELAYER_UPDATE_GEOMETRY(class3.InPtr, this.DataIndex, num);
                    HiMap.Carto.VC.KWG_GEOMETRY_CLEAR(num);
                    HiMap.Carto.VC.KWG_GEOMETRY_DELETE(num);
                }
            }
            class2.IsEdit();
        }

        void IFeature.SetValue(int Index, object Value)
        {
            IFeatureClass class2 = this._Class as IFeatureClass;
            if (class2.IsEdit())
            {
                this.listValue.set_Item(Index, Value);
                this._isDataUpdate = true;
            }
        }

        private void Ini(IFeatureClass Class)
        {
            this._Class = (ClassClass) Class;
            this.listValue = new List<object>();
        }

        private void setGeometry(int geometry_ptr)
        {
            IGeometryCollection geometrys;
            int num = HiMap.Carto.VC.KWG_GEOMETRY_GET_SEGMENT_COUNT(geometry_ptr);
            if (num == 0)
            {
                this._Shape = null;
                return;
            }
            IGeometry geometry = null;
            IGeometry[] geometryArray = null;
            switch (HiMap.Carto.VC.KWG_GEOMETRY_GET_TYPE(geometry_ptr))
            {
                case 1:
                case 11:
                case 0x15:
                {
                    IPoint point = new PointClass();
                    double x = 0;
                    double y = 0;
                    HiMap.Carto.VC.KWG_GEOMETRY_GET_POINTX(geometry_ptr, 0, ref x);
                    HiMap.Carto.VC.KWG_GEOMETRY_GET_POINTY(geometry_ptr, 0, ref y);
                    point.X = x;
                    point.Y = y;
                    this._Shape = point;
                    return;
                }
                case 8:
                case 0x12:
                case 0x1c:
                    geometry = new MultiPointClass();
                    geometryArray = new PointClass[num];
                    for (int i = 0; i < num; i++)
                    {
                        geometryArray[i] = new PointClass();
                    }
                    goto Label_0115;

                case 3:
                case 13:
                case 0x17:
                    geometry = new PolylineClass();
                    geometryArray = new PolylineClass[num];
                    for (int j = 0; j < num; j++)
                    {
                        geometryArray[j] = new PolylineClass();
                    }
                    goto Label_0115;

                case 5:
                case 15:
                case 0x19:
                    geometry = new PolygonClass();
                    geometryArray = new PolygonClass[num];
                    for (int k = 0; k < num; k++)
                    {
                        geometryArray[k] = new PolygonClass();
                    }
                    break;
            }
        Label_0115:
            geometrys = (IGeometryCollection) geometry;
            for (int m = 0; m < num; m++)
            {
                int num9 = HiMap.Carto.VC.KWG_GEOMETRY_GET_SEGMENT_POINT_COUNT(geometry_ptr, m);
                if (geometry.GetType() == typeof(MultiPointClass))
                {
                    IPoint newGeo = new PointClass();
                    double num10 = 0;
                    double num11 = 0;
                    HiMap.Carto.VC.KWG_GEOMETRY_GET_POINTX(geometry_ptr, m, ref num10);
                    HiMap.Carto.VC.KWG_GEOMETRY_GET_POINTY(geometry_ptr, m, ref num11);
                    newGeo.X = num10;
                    newGeo.Y = num11;
                    if (m == 0)
                    {
                        IMultiPoint point3 = (IMultiPoint) geometry;
                        point3.X = num10;
                        point3.Y = num11;
                        point3.M = 0;
                        point3.Z = 0;
                        geometrys.SetGeometry(m, newGeo);
                    }
                    else
                    {
                        geometrys.AddGeometry(newGeo);
                    }
                }
                else
                {
                    IPointCollection points = (IPointCollection) geometryArray[m];
                    for (int n = 0; n < num9; n++)
                    {
                        IPoint geo = new PointClass();
                        double num13 = 0;
                        double num14 = 0;
                        HiMap.Carto.VC.KWG_GEOMETRY_GET_SEGMENT_POINTX(geometry_ptr, m, n, ref num13);
                        HiMap.Carto.VC.KWG_GEOMETRY_GET_SEGMENT_POINTY(geometry_ptr, m, n, ref num14);
                        geo.X = num13;
                        geo.Y = num14;
                        points.AddPoint(geo);
                    }
                    if (m == 0)
                    {
                        geometrys = (IGeometryCollection) geometryArray[m];
                    }
                    else
                    {
                        geometrys.AddGeometry(geometryArray[m]);
                    }
                }
            }
            this._Shape = (IGeometry) geometrys;
        }

        IFeatureClass IFeature.Class
        {
            get
            {
                return (IFeatureClass) this._Class;
            }
        }

        IGeometry IFeature.Shape
        {
            get
            {
                return this._Shape;
            }
            set
            {
                this._Shape = value;
                this._isGeometryUpdate = true;
            }
        }
    }
}

